﻿using Brc_DSB.GetWay.Configuration;
using Brc_DSB.GetWay.DataBase;
using Brc_DSB.GetWay.Exceptionless;
using Brc_DSB.GetWay.Model;
using Brc_DSB.GetWay.Polly;
using Brc_DSB.GetWay.Redis;
using Brc_DSB.GetWay.Requester;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Options;
using Ocelot.Cache;
using Ocelot.Configuration;
using Ocelot.Configuration.File;
using Ocelot.Configuration.Repository;
using Ocelot.DependencyInjection;
using Ocelot.DownstreamRouteFinder;
using Ocelot.Errors;
using Ocelot.Logging;
using Ocelot.Provider.Polly;
using Ocelot.Requester;
using Polly.CircuitBreaker;
using Polly.Timeout;
using System;
using System.Collections.Generic;
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;

namespace Brc_DSB.GetWay.Middleware
{
    public delegate DelegatingHandler RetryDelegatingHandlerDelegate(DownstreamReRoute reRoute, IRetryRepository retry,IOcelotLoggerFactory logger);
    public static class ServiceCollectionExtensions
    {
        /// <summary>
        /// 添加默认的注入方式，所有需要传入的参数都是用默认值
        /// </summary>
        /// <param name="builder"></param>
        /// <returns></returns>
        public static IOcelotBuilder AddBrcGetWay(this IOcelotBuilder builder, Action<DbConfiguration> option)
        {
            builder.Services.Configure(option);
            //配置信息
            builder.Services.AddSingleton(resolver => resolver.GetRequiredService<IOptions<DbConfiguration>>().Value);
            //配置文件仓储注入
            builder.Services.AddSingleton<IFileConfigurationRepository, SqlServerFileConfigurationRepository>();
            //注入缓存
            builder.Services.AddSingleton<IOcelotCache<FileConfiguration>, RedisCache<FileConfiguration>>();
            builder.Services.AddSingleton<IOcelotCache<CachedResponse>, RedisCache<CachedResponse>>();
            builder.Services.AddSingleton<IInternalConfigurationRepository, RedisInternalConfigRepository>();

            //自定义权限验证注入
            builder.Services.AddSingleton<IOcelotCache<List<ServiceAuthModel>>, RedisCache<List<ServiceAuthModel>>>();
            builder.Services.AddSingleton<IAuthRepository, AuthRepository>();

            //自定义重试机制注入
            builder.Services.AddSingleton<IDelegatingHandlerHandlerFactory, ExtDelegatingHandlerHandlerFactory>();
            builder.Services.AddSingleton<IOcelotCache<GetWay_ReRouteRetry>, RedisCache<GetWay_ReRouteRetry>>();
            builder.Services.AddSingleton<IRetryRepository, RetryRepository>();
            builder.Services.AddSingleton<IRetryFactory, RetryFactory>();      
            DelegatingHandler RetryDelegatingHandlerDelegate(DownstreamReRoute route, IRetryRepository retry, IOcelotLoggerFactory logger)
            {
                return new RetryHandler(new PollyRetryProvider(retry, route, logger));
            }
            builder.Services.AddSingleton((RetryDelegatingHandlerDelegate)RetryDelegatingHandlerDelegate);

            //注入日志
            builder.Services.AddSingleton<IOcelotLoggerFactory, LogFactory>();

            builder.Services.AddSingleton<IOcelotCache<GetWay_WebService>, RedisCache<GetWay_WebService>>();
            builder.Services.AddSingleton<IWebServiceRepository, WebServiceRepository>();

            return builder;
        }

      
    }
    
}
